package cn.jinbyte.starter.captcha.service;


import cn.hutool.core.util.IdUtil;
import cn.jinbyte.starter.captcha.exception.CaptchaException;
import cn.jinbyte.starter.captcha.model.AbstractCaptcha;
import cn.jinbyte.starter.captcha.model.ImgCaptcha;
import cn.jinbyte.starter.captcha.config.EasyCaptchaProperties;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;

/**
 * <a href="https://gitee.com/ele-admin/EasyCaptcha">EasyCaptcha</a> Java开源图形验证码，支持gif、中文、算术等类型
 */
public class EasyCaptchaService implements ImgCaptchaService {
    private final EasyCaptchaProperties properties;
    private final CaptchaStore captchaStore;

    public EasyCaptchaService(EasyCaptchaProperties properties, CaptchaStore captchaStore) {
        this.properties = properties;
        this.captchaStore = captchaStore;
    }

    @Override
    public ImgCaptcha create() {
        String id = IdUtil.fastSimpleUUID();
        Captcha captcha = switch (properties.getType()) {
            case ARITHMETIC -> new ArithmeticCaptcha(
                    properties.getWidth(),
                    properties.getHeight(),
                    properties.getLength(),
                    properties.getFont()
            );
            case CHINESE -> new ChineseCaptcha(
                    properties.getWidth(),
                    properties.getHeight(),
                    properties.getLength()
            );
            case CHINESE_GIF -> new ChineseGifCaptcha(
                    properties.getWidth(),
                    properties.getHeight(),
                    properties.getLength()
            );
            case GIF -> new GifCaptcha(
                    properties.getWidth(),
                    properties.getHeight(),
                    properties.getLength()
            );
            case SPEC -> new SpecCaptcha(
                    properties.getWidth(),
                    properties.getHeight(),
                    properties.getLength()
            );
        };
        ImgCaptcha imgCaptcha = ImgCaptcha.of(captcha);
        imgCaptcha.setId(id);
        imgCaptcha.setExpires(System.currentTimeMillis() + properties.getTimeout() * 1000);
        captchaStore.put(id, imgCaptcha);
        return imgCaptcha;
    }

    @Override
    public void validate(String code, String id) {
        AbstractCaptcha abstractCaptcha = captchaStore.get(id);
        CaptchaException.throwIfExpired(abstractCaptcha == null);
        CaptchaException.throwIfExpired(abstractCaptcha.getExpires() < System.currentTimeMillis());
        CaptchaException.throwIfInvalid(!abstractCaptcha.getCode().equals(code));
        captchaStore.remove(id);
    }

    @Override
    public ImgCaptcha get(String uuid) {
        AbstractCaptcha abstractCaptcha = captchaStore.get(uuid);
        if (abstractCaptcha instanceof ImgCaptcha imgCaptcha) {
            return imgCaptcha;
        }
        return null;
    }
}
